package com.iotechn.microunimall.fee.service.biz;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.iotechn.microunimall.core.exception.AppServiceException;
import com.iotechn.microunimall.core.exception.ExceptionDefinition;
import com.iotechn.microunimall.core.exception.ServiceException;
import com.iotechn.microunimall.fee.api.domain.FreightTemplateCarriageDO;
import com.iotechn.microunimall.fee.api.domain.FreightTemplateDO;
import com.iotechn.microunimall.fee.api.dto.FreightCalcRequest;
import com.iotechn.microunimall.fee.api.dto.FreightTemplateDTO;
import com.iotechn.microunimall.fee.api.dto.ShipTraceDTO;
import com.iotechn.microunimall.fee.api.service.biz.FreightBizService;
import com.iotechn.microunimall.fee.mapper.FreightTemplateCarriageMapper;
import com.iotechn.microunimall.fee.mapper.FreightTemplateMapper;
import com.iotechn.microunimall.fee.query.ShipTraceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: rize
 * Date: 2019/11/11
 * Time: 19:03
 */
@Service("freightBizService")
public class FreightBizServiceImpl implements FreightBizService {

    @Autowired
    private FreightTemplateMapper freightTemplateMapper;

    @Autowired
    private FreightTemplateCarriageMapper freightTemplateCarriageMapper;

    @Autowired
    private ShipTraceQuery shipTraceQuery;

    //根据传入的订单数据，计算邮费
    @Override
    public Integer getFreightMoney(FreightCalcRequest freightCalcRequest) throws ServiceException {
        //策略ID 数量映射
        Map<Long, Integer> map = freightCalcRequest.getMap();
        int price = 0;
        for (Long freightId : map.keySet()) {
            FreightTemplateDO freightTemplateDO = freightTemplateMapper.selectById(freightId);
            List<FreightTemplateCarriageDO> freightTemplateCarriageDOList =
                    freightTemplateCarriageMapper.selectList(
                            new EntityWrapper<FreightTemplateCarriageDO>()
                                .eq("template_id", freightTemplateDO.getId()));

            Integer necessary = freightTemplateDO.getNecessary();
            if (necessary == 1 && freightCalcRequest.getProvince() == null) {
                throw new AppServiceException(ExceptionDefinition.FREIGHT_ADDRESS_IS_NECESSARY);
            }

            FreightTemplateDTO tempDTO = new FreightTemplateDTO(freightTemplateDO, freightTemplateCarriageDOList);
            price += getMoney(tempDTO, map.get(freightId), freightCalcRequest.getProvince(), freightCalcRequest.getPrice());
        }
        return price;
    }

    //根据传入的运费模板信息\使用同一模板商品数量\快递省份地址\使用同一模板商品总价减使用的优惠卷，计算这类商品在该订单中的运费
    private Integer getMoney(FreightTemplateDTO freightTemplateDTO, Integer num, String province, Integer moneySubDiscount) {

        List<FreightTemplateCarriageDO> freightTemplateCarriageDOList = freightTemplateDTO.getFreightTemplateCarriageDOList();

        //先遍历是否是属于非默认运费规则，如果是，计算并返回值
        for (FreightTemplateCarriageDO freightTemplateCarriageDO : freightTemplateCarriageDOList) {
            //邮寄地址省份在其中
            if (freightTemplateCarriageDO.getDesignatedArea().contains(province)) {
                //如果包邮返回0
                if (freightTemplateCarriageDO.getFreePrice() == 0) {
                    return 0;
                }
                //必须为正数才是满邮活动
                if (moneySubDiscount >= freightTemplateCarriageDO.getFreePrice() && freightTemplateCarriageDO.getFreePrice() > 0) {
                    return 0;
                }

                Integer open = freightTemplateCarriageDO.getFirstMoney();
                num = num - freightTemplateCarriageDO.getFirstNum();

                //该订单中使用该运费模板的商品总数小于或等于该运费模板的起价的件数
                if (num <= 0) {
                    return open;
                }

                if (num % freightTemplateCarriageDO.getContinueNum() != 0) {
                    open = open + freightTemplateCarriageDO.getContinueMoney() * ((num / freightTemplateCarriageDO.getContinueNum()) + 1);
                } else {
                    open = open + freightTemplateCarriageDO.getContinueMoney() * (num / freightTemplateCarriageDO.getContinueNum());
                }
                return open;
            }
        }

        //如果使用默认运费规则
        FreightTemplateDO freightTemplateDO = freightTemplateDTO.getFreightTemplateDO();

        if (freightTemplateDO.getDefaultFreePrice() == 0) {
            return 0;
        }
        if (freightTemplateDO.getDefaultFreePrice() > 0 && moneySubDiscount >= freightTemplateDO.getDefaultFreePrice()) {
            return 0;
        }

        Integer open = freightTemplateDO.getDefaultFirstMoney();
        num = num - freightTemplateDO.getDefaultFirstNum();

        //该订单中使用该运费模板的商品总数小于或等于该运费模板的起价的件数
        if (num <= 0) {
            return open;
        }

        if (num % freightTemplateDO.getDefaultContinueNum() != 0) {
            open = open + freightTemplateDO.getDefaultContinueMoney() * ((num / freightTemplateDO.getDefaultContinueNum()) + 1);
        } else {
            open = open + freightTemplateDO.getDefaultContinueMoney() * (num / freightTemplateDO.getDefaultContinueNum());
        }
        return open;
    }

    @Override
    public FreightTemplateDTO getTemplateById(Long templateId) throws ServiceException {
        FreightTemplateDO freightTemplateDO = freightTemplateMapper.selectById(templateId);
        if (freightTemplateDO == null) {
            throw new AppServiceException(ExceptionDefinition.FREIGHT_TEMPLATE_NOT_EXIST);
        }

        //查出副表中其他地区的东西
        List<FreightTemplateCarriageDO> freightTemplateCarriageDOList = freightTemplateCarriageMapper.selectList(new EntityWrapper<FreightTemplateCarriageDO>()
                .eq("template_id", freightTemplateDO.getId()));

        FreightTemplateDTO freightTemplateDTO = new FreightTemplateDTO(freightTemplateDO, freightTemplateCarriageDOList);
        return freightTemplateDTO;
    }

    /**
     * 本来这个应该放在订单 或者 供应链的 ，但是为了适配之前的接口，就放在这里了
     * @param shipNo
     * @param shipCode
     * @return
     * @throws ServiceException
     */
    @Override
    public ShipTraceDTO getShipTraceList(String shipNo, String shipCode) throws ServiceException {
        return shipTraceQuery.query(shipNo, shipCode);
    }

}
